package com.shop.util;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtil {

    private static final String STR_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    private static final String STR_DATE = "yyyy-MM-dd";
    private static final String STR_SHORT_DATE_TIME = "yyyyMMddHHmmss";
    private static final String STR_SHORT_DATE_TIME_MS = "yyyyMMddHHmmssSSS";
    private static final String STR_SHORT_DATE_TIME_YEAR = "yyMMddHHmmss";
    private static final String STR_SHORT_DATE = "yyyyMMdd";
    private static final String STR_MONTH_FIRST_DATE = "yyyyMM";
    private static final String STR_TIME = "HH:mm:ss";

    public static Date timestamp2Date(long timestamp) {
        Date date = new Date();
        date.setTime(timestamp);
        return date;
    }

    /**
     * 解析日期
     */
    public static Date parseDate(String str, String format) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(format).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    public static String getTodayDatetime() {
        return new SimpleDateFormat(STR_DATE_TIME).format(new Date());
    }

    public static String getTodayDate() {
        return new SimpleDateFormat(STR_DATE).format(new Date());
    }

    public static String getTodayShortDatetime() {
        return new SimpleDateFormat(STR_SHORT_DATE_TIME).format(new Date());
    }

    public static String getTodayShortDatetimeMs() {
        return new SimpleDateFormat(STR_SHORT_DATE_TIME_MS).format(new Date());
    }

    public static String getTodayShortDatetimeYear() {
        return new SimpleDateFormat(STR_SHORT_DATE_TIME_YEAR).format(new Date());
    }

    public static String getTodayShortDate() {
        return new SimpleDateFormat(STR_SHORT_DATE).format(new Date());
    }


    /**
     * 格式化日期
     */
    public static String format(Date date, String formatPattern) {
        if (null == date) return null;

        return new SimpleDateFormat(formatPattern).format(date);
    }

    /**
     * yyyy-MM-dd HH:mm:ss 格式化时间日期
     */
    public static String formatDatetime(Date datetime) {
        if (null == datetime) return null;
        return new SimpleDateFormat(STR_DATE_TIME).format(datetime);
    }

    /**
     * yyyy-MM-dd 格式化日期
     */
    public static String formatDate(Date date) {
        if (null == date) return null;

        return new SimpleDateFormat(STR_DATE).format(date);
    }

    /**
     * HH:mm:ss 格式化时间
     */
    public static String formatTime(Date time) {
        if (null == time) return null;

        return new SimpleDateFormat(STR_TIME).format(time);
    }

    /**
     * yyyy-MM-dd HH:mm:ss 解析时间日期
     */
    public static Date parseDatetime(String str) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(STR_DATE_TIME).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * yyyy-MM-dd 解析日期
     */
    public static Date parseDate(String str) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(STR_DATE).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * HH:mm:ss 解析时间
     */
    public static Date parseTime(String str) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(STR_TIME).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * yyyyMMddHHmmss 格式化时间日期
     */
    public static String formatShortDatetime(Date datetime) {
        if (null == datetime) return null;
        return new SimpleDateFormat(STR_SHORT_DATE_TIME).format(datetime);
    }

    /**
     * yyyyMMdd 格式化日期
     */
    public static String formatShortDate(Date date) {
        if (null == date) return null;

        return new SimpleDateFormat(STR_SHORT_DATE).format(date);
    }


    /**
     * yyyyMMdd 格式化每月首日日期
     */
    public static String formatMonth(Date date) {
        if (null == date) return null;

        return new SimpleDateFormat(STR_MONTH_FIRST_DATE).format(date);
    }

    /**
     * yyyyMMddHHmmss 解析时间日期
     */
    public static Date parseShortDatetime(String str) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(STR_SHORT_DATE_TIME).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * yyyyMMdd 解析日期
     */
    public static Date parseShortDate(String str) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(STR_SHORT_DATE).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * yyyyMMdd 解析每月首日日期
     */
    public static Date parseMonthFirstDate(String str) {
        if (StringUtils.isEmpty(str)) return null;

        Date date = null;
        try {
            date = new SimpleDateFormat(STR_MONTH_FIRST_DATE).parse(str);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    private static Date add(Date date, int type, int value) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(type, value);
        return calendar.getTime();
    }

    /**
     * 日期加上小时的时间
     *
     * @param date
     * @param min
     * @return Date
     */
    public static Date dateAddMinute(Date date, int min) {
        return add(date, Calendar.MINUTE, min);
    }

    /**
     * 日期加上小时的时间
     *
     * @param date
     * @param hour
     * @return Date
     */
    public static Date dateAddHour(Date date, int hour) {
        return add(date, Calendar.HOUR_OF_DAY, hour);
    }

    /**
     * 日期加上天数的时间
     *
     * @param date
     * @param day
     * @return
     */
    public static Date dateAddDay(Date date, int day) {
        return add(date, Calendar.DAY_OF_YEAR, day);
    }

    /**
     * 日期加上月数的时间
     *
     * @param date
     * @param month
     * @return
     */
    public static Date dateAddMonth(Date date, int month) {
        return add(date, Calendar.MONTH, month);
    }

    /**
     * 日期加上年数的时间
     *
     * @param date
     * @param year
     * @return
     */
    public static Date dateAddYear(Date date, int year) {
        return add(date, Calendar.YEAR, year);
    }

    /**
     * 日期加上天数区间所有的日期
     *
     * @param date
     * @param day
     * @return
     * @author yzChen
     * @date 2017年2月22日 下午10:45:06
     */
    public static List<Date> dateAddDayGetDates(Date date, int day) {
        List<Date> list = new ArrayList<>();
        if (day == 0) return list;

        Date addDate = dateAddDay(date, day);
        Date beginDate = day > 0 ? date : addDate;
        Date endDate = day < 0 ? date : addDate;
        do {
            list.add(beginDate);
            beginDate = dateAddDay(beginDate, 1);
        } while (beginDate.getTime() <= endDate.getTime());
        return list;
    }

    /**
     * 两个日期区间所有的日期
     *
     * @param beginDate
     * @param endDate
     * @return
     * @author yzChen
     * @date 2017年2月22日 下午10:45:06
     */
    public static List<Date> dateBetweenGetDates(Date beginDate, Date endDate) {
        List<Date> list = new ArrayList<>();
        do {
            list.add(beginDate);
            beginDate = dateAddDay(beginDate, 1);
        } while (beginDate.getTime() <= endDate.getTime());
        return list;
    }

    /**
     * 日期加上月数区间所有的日期
     *
     * @param date
     * @param month
     * @return
     * @author yzChen
     * @date 2017年2月22日 下午10:45:06
     */
    public static List<Date> dateAddMonthGetDates(Date date, int month) {
        List<Date> list = new ArrayList<>();
        if (month == 0) return list;

        Date addDate = dateAddMonth(date, month);
        Date beginDate = month > 0 ? date : addDate;
        Date endDate = month < 0 ? date : addDate;
        do {
            list.add(beginDate);
            beginDate = dateAddDay(beginDate, 1);
        } while (beginDate.getTime() <= endDate.getTime());
        return list;
    }

    /**
     * 日期加上年数区间所有的每月当日日期
     *
     * @param date
     * @param year
     * @return
     * @author yzChen
     * @date 2017年2月22日 下午10:45:06
     */
    public static List<Date> dateAddYearGetDates(Date date, int year) {
        List<Date> list = new ArrayList<>();
        if (year == 0) return list;

        Date addDate = dateAddYear(date, year);
        Date beginDate = year > 0 ? date : addDate;
        Date endDate = year < 0 ? date : addDate;
        do {
            list.add(beginDate);
            beginDate = dateAddMonth(beginDate, 1);
        } while (beginDate.getTime() <= endDate.getTime());
        return list;
    }

    /**
     * yyyyMMdd 00:00:00 截断日期到凌晨
     */
    public static Date cutDateYYYYMMDD000000(Date date) {
        if (null == date) return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * yyyyMMdd 23:59:59 截断日期到最后一秒
     */
    public static Date cutDateYYYYMMDD235959(Date date) {
        if (null == date) return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * yyyyMM01 00:00:00 截断日期到月份首日
     */
    public static Date cutDateYYYYMM01000000(Date date) {
        if (null == date) return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * yyyyMM01 00:00:00 截断日期到年份首日
     */
    public static Date cutDateYYYY0101000000(Date date) {
        if (null == date) return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MONTH, 0);
        return calendar.getTime();
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime 当前时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     * @author jqlin
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }
}
